const Joi = require('joi');

/**
 * 数据验证服务
 */
class ValidationService {
  constructor() {
    // 定义验证模式
    this.scoreSchema = Joi.object({
      row: Joi.number().required(),
      studentId: Joi.string().max(20).required()
        .messages({
          'string.empty': '准考证号不能为空',
          'string.max': '准考证号不能超过20个字符',
          'any.required': '准考证号是必填项'
        }),
      className: Joi.string().max(50).allow(null, '')
        .messages({
          'string.max': '班级名称不能超过50个字符'
        }),
      name: Joi.string().max(50).required()
        .messages({
          'string.empty': '姓名不能为空',
          'string.max': '姓名不能超过50个字符',
          'any.required': '姓名是必填项'
        }),
      chinese: Joi.number().min(0).max(150).allow(null)
        .messages({
          'number.min': '语文成绩不能小于0',
          'number.max': '语文成绩不能超过150'
        }),
      math: Joi.number().min(0).max(150).allow(null)
        .messages({
          'number.min': '数学成绩不能小于0',
          'number.max': '数学成绩不能超过150'
        }),
      english: Joi.number().min(0).max(150).allow(null)
        .messages({
          'number.min': '英语成绩不能小于0',
          'number.max': '英语成绩不能超过150'
        }),
      physics: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '物理成绩不能小于0',
          'number.max': '物理成绩不能超过100'
        }),
      chemistry: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '化学成绩不能小于0',
          'number.max': '化学成绩不能超过100'
        }),
      biology: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '生物成绩不能小于0',
          'number.max': '生物成绩不能超过100'
        }),
      politics: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '政治成绩不能小于0',
          'number.max': '政治成绩不能超过100'
        }),
      history: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '历史成绩不能小于0',
          'number.max': '历史成绩不能超过100'
        }),
      geography: Joi.number().min(0).max(100).allow(null)
        .messages({
          'number.min': '地理成绩不能小于0',
          'number.max': '地理成绩不能超过100'
        }),
      totalScore: Joi.number().min(0).max(1000).allow(null)
        .messages({
          'number.min': '总分不能小于0',
          'number.max': '总分不能超过1000'
        }),
      schoolRank: Joi.number().integer().min(1).allow(null)
        .messages({
          'number.base': '校次必须是整数',
          'number.min': '校次必须大于0'
        })
    });
  }

  /**
   * 验证单条记录
   * @param {Object} data - 待验证的数据
   * @returns {Object} 验证结果 { valid: boolean, error: string|null, data: Object }
   */
  validateRecord(data) {
    // 预处理：将数字类型的 studentId 转换为字符串
    if (data.studentId !== null && data.studentId !== undefined) {
      data.studentId = String(data.studentId);
    }
    
    // 预处理：将数字类型的 name 转换为字符串
    if (data.name !== null && data.name !== undefined) {
      data.name = String(data.name);
    }
    
    const { error, value } = this.scoreSchema.validate(data, {
      abortEarly: false,
      stripUnknown: true
    });

    if (error) {
      const errorMessages = error.details.map(detail => detail.message).join('; ');
      return {
        valid: false,
        error: errorMessages,
        data: value
      };
    }

    return {
      valid: true,
      error: null,
      data: value
    };
  }

  /**
   * 批量验证记录
   * @param {Array} records - 待验证的记录数组
   * @returns {Object} 验证结果 { validRecords: Array, invalidRecords: Array }
   */
  validateBatch(records) {
    const validRecords = [];
    const invalidRecords = [];

    records.forEach(record => {
      // 如果记录本身就有错误（解析错误），直接标记为无效
      if (record.error) {
        invalidRecords.push({
          row: record.row,
          reason: record.error,
          data: record.rawData || record
        });
        return;
      }

      const result = this.validateRecord(record);
      
      if (result.valid) {
        validRecords.push(result.data);
      } else {
        invalidRecords.push({
          row: record.row,
          studentId: record.studentId,
          name: record.name,
          reason: result.error,
          data: record
        });
      }
    });

    return {
      validRecords,
      invalidRecords,
      summary: {
        total: records.length,
        valid: validRecords.length,
        invalid: invalidRecords.length
      }
    };
  }

  /**
   * 验证文件上传参数
   * @param {Object} params - 上传参数
   * @returns {Object} 验证结果
   */
  validateUploadParams(params) {
    const schema = Joi.object({
      examName: Joi.string().max(100).required()
        .messages({
          'string.empty': '考试名称不能为空',
          'string.max': '考试名称不能超过100个字符',
          'any.required': '考试名称是必填项'
        }),
      examDate: Joi.date().required()
        .messages({
          'date.base': '考试日期格式不正确',
          'any.required': '考试日期是必填项'
        })
    });

    const { error, value } = schema.validate(params);

    if (error) {
      return {
        valid: false,
        error: error.details[0].message
      };
    }

    return {
      valid: true,
      data: value
    };
  }
}

module.exports = new ValidationService();
